package com.lotee.smarqueeview;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.animation.LinearInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.AppCompatTextView;


/**
 * @author wtl
 * @date 2019/10/25.
 * description：可自动滚动的TextView
 */

public class ScrollTextView extends AppCompatTextView {
    private @Nullable String text;
    private Paint paint = new Paint();
    private ValueAnimator animator = new ValueAnimator();
    private int dx = 0;
    private Rect rect = new Rect();
    private ScrollEvent scrollEvent;

    public ScrollTextView(Context context) {
        this(context, null);
    }

    public ScrollTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScrollTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, getResources().getDisplayMetrics()));
        paint.setColor(Color.BLACK);

        //设置跑马灯动画 保证不同长度滚动速度相同
        LinearInterpolator linearInterpolator = new LinearInterpolator();
        animator.setInterpolator(linearInterpolator);

//        animator.setStartDelay(500);
        animator.addListener(new Animator.AnimatorListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onAnimationStart(final Animator animation) {
                // 先置于最前 停顿一下不至于过快看不清
                animation.pause();
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        animation.resume();
                    }
                }, 500);
            }

            @Override
            public void onAnimationEnd(Animator animation) {

                scrollEvent.onScrollEnd(500);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.addUpdateListener(animation -> {
                    dx = -(int) animation.getAnimatedValue();
                    invalidate();
                });
    }

    public void setScrollEvent(ScrollEvent scrollEvent) {
        this.scrollEvent = scrollEvent;
    }

    /**
     * 滚动事件接口
     */
    public interface ScrollEvent {
        void onScrollEnd(long duration);
    }

    public void setText(@NonNull String text) {
        this.text = text;
    }

    /**
     * 开启滚动 若无滚动则发送滚动结束事件
     *
     * @param dx
     */
    public void start(int dx) {
        animator.setIntValues(0, dx);
        long duration = 35 * dx / 2;
        animator.setDuration(duration < 0 ? 0 : duration);
        if (dx <= 0) {
            scrollEvent.onScrollEnd(3000);
        } else {
            animator.start();
        }
    }

    public void reset() {
        dx = 0;
    }

    public int getTextWidth() {
        if (text != null) {
            paint.getTextBounds(text, 0, text.length(), rect);
            return rect.width();
        } else {
            return 0;
        }
    }

    public int getTextHeight() {
        if (text != null) {
            paint.getTextBounds(text, 0, text.length(), rect);
            return rect.height();
        } else {
            return 0;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (text == null) {
            return;
        }
        paint.getTextBounds(text, 0, text.length(), rect);
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        float baseLine = (getHeight() - fontMetrics.bottom - fontMetrics.top) / 2;
        canvas.drawText(text, dx, baseLine, paint);
    }
}